
#ifndef rtps_MemoryPool_H
#define rtps_MemoryPool_H

#include "rtps/common/types.h"
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define RTPS_MEMORYPOOL_ITER(pmp, offset, ptmp, pblk, pdata)  \
    for((offset)=0, (ptmp)=((pmp)->mrp_addr), (pblk) = *(uint8_t **)ptmp, (pdata)=((ptmp) + sizeof(uint8_t*)); \
        ((offset) < ((pmp)->blk_total - 1)); \
        (offset)++, \
        ptmp += ((pmp)->blk_size + sizeof(uint8_t *)),\
        (pblk) = *(uint8_t **)ptmp,\
        (pdata) = ((ptmp) + sizeof(uint8_t*))) \
        if ((pblk) == (uint8_t*)(pmp))

typedef bool (*rtps_MemoryPool_jumppad)(void *pda, void *pdb);

struct rtps_MemoryPool {
    void     *mrp_addr;          /**< memory pool address */
    uint32_t  mrp_size;          /**< memory pool size*/
    uint32_t  blk_total;         /**< memory block number total */
    uint32_t  blk_free;          /**< memory block number unused */
    uint32_t  blk_size;          /**< memory block size */
    uint8_t  *blk_list;          /**< memory block list pointer */
};

struct rtps_MemoryPool *
rtps_MemoryPool_init(uint32_t blk_size, uint32_t blk_cnt);

void
rtps_MemoryPool_deinit(struct rtps_MemoryPool *pmp);

uint32_t
rtps_MemoryPool_getSize(struct rtps_MemoryPool *pmp);

bool
rtps_MemoryPool_isFull(struct rtps_MemoryPool *pmp);

bool
rtps_MemoryPool_isEmpty(struct rtps_MemoryPool *pmp);

uint32_t
rtps_MemoryPool_getNumElements(struct rtps_MemoryPool *pmp);

bool
rtps_MemoryPool_add(struct rtps_MemoryPool *pmp, void *data);

bool
rtps_MemoryPool_remove(
    struct rtps_MemoryPool *pmp, 
    rtps_MemoryPool_jumppad jumppad,
    void *isCorrectElement);

bool
rtps_MemoryPool_find(
    struct rtps_MemoryPool *pmp, 
    rtps_MemoryPool_jumppad jumppad,
    void *isCorrectElement);

bool
rtps_MemoryPool_getElement(
    struct rtps_MemoryPool *pmp,
    rtps_MemoryPool_jumppad jumppad,
    void *isCorrectElement,
    void *findElement,
    uint32_t size);
bool
rtps_MemoryPool_getElement_not_safe(
    struct rtps_MemoryPool *pmp,
    rtps_MemoryPool_jumppad jumppad,
    void *isCorrectElement,
    void **findElement);

#ifdef __cplusplus
}
#endif

#endif